package com.topscomm.gpm.xxljob;

/**
 * @author liwanpeng
 * @version 1.0
 * @description: TODO
 * @date 2021/6/18 9:09
 */

import com.topscomm.basic.BasicEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.cbo.service.impl.CboApprovalNodeInsService;
import com.topscomm.cbo.service.impl.CboUserService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.gpm.pojo.GpmProjectEntity;
import com.topscomm.gpm.pojo.GpmProjectTaskEntity;
import com.topscomm.gpm.service.impl.GpmProjectService;
import com.topscomm.gpm.service.impl.GpmProjectTaskService;
import com.topscomm.gpm.utils.GetContextUtil;
import com.topscomm.tap.TapService;
import com.topscomm.tap.common.DatacodeCache;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * @author liwanpeng
 * @date 2021/06/18
 * @description: 检查我的待办，如果存在待办任务则发送待办提醒。
 * @modify:
 */
@JobHandler(value = "backlogRemind")
@Component
public class BacklogRemind extends IJobHandler {
    private static final Logger log = LoggerFactory.getLogger(BacklogRemind.class);
    @Autowired
    private CboApprovalNodeInsService cboApprovalNodeInsService;
    @Autowired
    private CboUserService cboUserService;
    @Autowired
    private ICboMessageSysService cboMessageSysService;
    @Autowired
    private ICboMessageAppService cboMessageAppService;
    @Autowired
    private GpmProjectTaskService gpmProjectTaskService;
    @Autowired
    private GpmProjectService gpmProjectService;

    @Override
    public ReturnT<String> execute(String param) {

        try {
            StringBufferProxy sql = new StringBufferProxy();
//            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
//            String format = simpleDateFormat.format(new Date());
//            sql.appendSingle("SALARYDAY={0} ", SQLAdapter.toDateLong(format));
//            MpmWorkingCalendarEntity mpmWorkingCalendarEntity = mpmWorkingCalendarService
//                .queryByWhere(sql.toString()).get(0);
//            if("01".equals(mpmWorkingCalendarEntity.getCategory())) {
            // 查询SD项目的所有待办项
            StringBufferProxy whereSql = new StringBufferProxy();
            whereSql.appendSingle(" state = 1 and sourcetype like 'Gpm%' ");
            List<Map<String, Object>> nodeInsList = cboApprovalNodeInsService.queryMapByWhere(whereSql.toString());
            // 按照用户id进行分组
            Map<String, List<Map<String, Object>>> backlogGroupByUserId = nodeInsList.stream().collect(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.get("approvaluserid"))));
            Set<Entry<String, List<Map<String, Object>>>> entries = backlogGroupByUserId.entrySet();
            // 遍历集合，给存在待办事项的人发送待办提醒
            List<Map<String, Object>> sysMessageList = new ArrayList<>();
            List<Map<String, Object>> appMessageList = new ArrayList<>();

            DatacodeCache datacodeCache = (DatacodeCache) SpringUtil.getBean("datacodeCache");
            for (Entry<String, List<Map<String, Object>>> item : entries) {
                // 根据用户ID查询用户信息
                CboUserEntity cboUserEntity = cboUserService.queryById(item.getKey());
                // 查询已下发未开始的任务
                sql.clear();
                if (cboUserEntity != null) {
                    sql.appendSingle("state=9 and taskstate=0 and responsiblecode='{0}'", cboUserEntity.getCode());
                    List<GpmProjectTaskEntity> sdProjectTaskEntities = gpmProjectTaskService.queryByWhere(sql.toString());
                    if (sdProjectTaskEntities.size() > 0) {
                        for (GpmProjectTaskEntity entity : sdProjectTaskEntities) {
                            long nowseconds = entity.getModifiedon().getTime();
                            long datetime = new Date().getTime();
                            long t = (datetime - nowseconds) / (1000 * 60 * 60);
                            // job任务定为工作日9点、执行，最新改动时间和这些时间的差值为2小时，提醒，否则不提醒
                            if (t < 2L) {
                                continue;
                            } else {
                                // app提醒
                                String taskcontent = entity.getTaskname() + "已派发给您，请及时开始任务。";
                                Map<String, Object> taskappmap = insertMessageApp(entity.getResponsiblecode(), "通用项目管理任务提醒", taskcontent,
                                        entity.getId(), "gpm-backlogRemind", 0);
                                cboMessageAppService.insertMap(taskappmap);
                                // 系统提醒
                                Map<String, Object> taskSysMap = insertMessageSys(entity.getResponsiblecode(), entity.getResponsible(), "通用项目管理任务提醒",
                                        taskcontent, entity.getId(), "gpm-backlogRemind");
                                cboMessageSysService.insertMap(taskSysMap);
                            }
                        }
                    }
                    // 遍历该用户下所有审批节点实例，逐条发送APP消息提醒
                    List<Map<String, Object>> itemvalueList = item.getValue();
                    Map<String, List<Map<String, Object>>> nodeInsListMap = itemvalueList.stream().collect(Collectors
                            .groupingBy(map -> ConvertUtil.convertToString(map.get("nodeid")) + ConvertUtil.convertToString(map.get("sourceid"))));
                    Set<Entry<String, List<Map<String, Object>>>> entries1 = nodeInsListMap
                            .entrySet();
                    StringBufferProxy backLogSql = new StringBufferProxy();
                    for (Entry<String, List<Map<String, Object>>> itemEntry : entries1) {
                        List<Map<String, Object>> value = itemEntry.getValue();
                        Date modifiedon = (Date) value.get(0).get("modifiedon");
                        long modifiedontime = modifiedon.getTime();
                        long datetime = new Date().getTime();
                        long t = (datetime - modifiedontime) / (1000 * 60 * 60);
                        // job任务定为工作日9点、执行，最新改动时间和这些时间的差值为2小时，提醒，否则不提醒
                        if (t < 2L) {
                            continue;
                        }
                        // 给审批人发送App提醒
                        String valueDynamic = datacodeCache.getValueDynamic("CboApprovalFlowCategory", ConvertUtil.convertToString(value.get(0).get("sourcetype")), "code", "name");
                        // 获取当前审批节点的项目信息
                        String projectName = "";
                        String sourcetype = value.get(0).get("sourcetype").toString();
                        String sourceid = value.get(0).get("sourceid").toString();
                        String lowerFirst = Character.toLowerCase(sourcetype.charAt(0)) +
                                sourcetype.substring(1);
                        String serviceName = lowerFirst + "Service";
                        ApplicationContext applicationContext = GetContextUtil
                                .getApplicationContext();
                        if (!applicationContext.containsBean(serviceName)) {
                            continue;
                        }
                        TapService serviceBean = (TapService) SpringUtil.getBean(serviceName);
                        BasicEntity selectEntity = serviceBean.queryById(sourceid);
                        if (selectEntity == null) {
                            continue;
                        }
                        if ("gpmWfFormService".equals(serviceName)) {
                            // 立项、立项变更项目名称查询
                            GpmProjectEntity gpmProjectEntity = gpmProjectService.queryById(ConvertUtil.convertToString(selectEntity.getValue("finalsourceid")));
                            if (gpmProjectEntity != null) {
                                projectName = gpmProjectEntity.getProjectname();
                            }
                        } else if ("gpmProjectTaskFeedbackService".equals(serviceName) || "gpmProjectTaskCloseService".equals(serviceName)) {
                            // 任务反馈、任务关闭项目名称查询
                            backLogSql.clear();
                            backLogSql.appendSingle(" projectcode=(select projectcode from GPMprojecttask where id = '{0}') ",
                                    ConvertUtil.convertToString(selectEntity.getValue("taskid")));
                            List<GpmProjectEntity> sdProjectEntities = gpmProjectService
                                    .queryByWhere(backLogSql.toString());
                            if (sdProjectEntities.size() > 0) {
                                projectName = sdProjectEntities.get(0).getProjectname();
                            }
                        } else {
                            // 项目名称查询
                            backLogSql.clear();
                            backLogSql.appendSingle(" projectcode='{0}'", ConvertUtil.convertToString(selectEntity.getValue("projectcode")));
                            List<GpmProjectEntity> sdProjectEntities = gpmProjectService
                                    .queryByWhere(backLogSql.toString());
                            if (sdProjectEntities.size() > 0) {
                                projectName = sdProjectEntities.get(0).getProjectname();
                            }
                        }
                        String approvalUserContent = "【" + projectName + "】" + valueDynamic + "流程的" + value.get(0).get("dispnodeid") + "节点的审批通知，" + "等待审批已经过" + t + "小时，请您及时办理。";
                        Map<String, Object> inserAppMap = insertMessageApp(cboUserEntity.getCode(), "通用项目管理审批办理提醒", approvalUserContent,
                                ConvertUtil.convertToLong(value.get(0).get("sourceid")), "gpm-backlogRemind", 0);
                        cboMessageAppService.insertMap(inserAppMap);
                        // 给审批人发送系统消息
                        Map<String, Object> inserSysMap = insertMessageSys(cboUserEntity.getCode(), cboUserEntity.getName(), "通用项目管理审批办理提醒",
                                approvalUserContent, ConvertUtil.convertToLong(value.get(0).get("sourceid")), "gpm-backlogRemind");
                        cboMessageSysService.insertMap(inserSysMap);
                        // 遍历待办事项，如果有属于立项流程的待办，也给项目经理发送提醒
                        if ("GpmWfForm".equals(value.get(0).get("sourcetype"))) {
                            whereSql.clear();
                            whereSql.appendSingle("select project.* from GPMwfform form inner join gpmproject project on form.sourceid = project.id " +
                                            "where form.id = '{0}' and form.sourcetype = '{1}'",
                                    value.get(0).get("sourceid"), GpmProjectEntity.tableName);
                            List<Map<String, Object>> res = gpmProjectService.selectExecute(whereSql.toString());
                            GpmProjectEntity gpmProjectEntity = new GpmProjectEntity();
                            if (res.size() == 0) {
                                continue;
                            } else {
                                gpmProjectEntity = (GpmProjectEntity) gpmProjectEntity.convertFromMap(res.get(0));
                            }
                            //插入App消息
                            String managercontent = "【" + gpmProjectEntity.getProjectname() + "】项目立项流程的" + value.get(0).get("dispnodeid") + "节点的" + cboUserEntity.getName() + "审批已用时" + t + "小时,请及时沟通提醒。";
                            Map<String, Object> insertAppMap = insertMessageApp(gpmProjectEntity.getProjectmanagercode(), "通用项目管理立项沟通提醒", managercontent,
                                    gpmProjectEntity.getId(), "gpm-backlogRemind", 0);
                            cboMessageAppService.insertMap(insertAppMap);
                            // 插入系统消息
                            Map<String, Object> insertSysMap = insertMessageSys(gpmProjectEntity.getProjectmanagercode(), gpmProjectEntity.getProjectmanager(), "通用项目立项沟通提醒",
                                    managercontent, gpmProjectEntity.getId(), "gpm-backlogRemind");
                            cboMessageSysService.insertMap(insertSysMap);
                        }
                    }
                }
            }
//            }
            return ReturnT.SUCCESS;
        } catch (Exception e) {
            log.error("发送待办提示失败", e);
            return new ReturnT(ReturnT.FAIL_CODE, e.getMessage());
        }
    }

    /**
     * @author: houyuhang
     * @date: 2021-01-05
     * @description: 插入系统消息
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     * @modify:
     */
    public Map<String, Object> insertMessageSys(String usercode, String username, String title, String content, long sourceid, String sourcetype) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("receivercode", usercode);
        map.put("receivername", username);
        map.put("subject", title);
        map.put("content", content);
        map.put("sourceid", sourceid);
        map.put("sourcetype", sourcetype);
        return map;
    }

    /**
     * @author: houyuhang
     * @date: 2021-1-5
     * @description: 插入App消息
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     * @modify:
     */
    public Map<String, Object> insertMessageApp(String usercode, String extendfield1, String content, long sourceid, String sourcetype, int sendtype) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("usercode", usercode);
        map.put("extendfield1", extendfield1);
        map.put("content", content);
        map.put("sourceid", sourceid);
        map.put("sourcetype", sourcetype);
        map.put("sendtype", sendtype);
        return map;
    }
}
